vlwkaos' digital garden

chunks

#[allow(unused_imports)]
use std::cmp::{min, max};


fn main() {
    let my_vec = vec![-878, 879, 1928, 0, -129];
    // .iter() 이므로 borrowed 
    // &i32와 i32간 비교 연산은 정의되어있지 않으므로 dereference해야함
    let biggest = my_vec
        .iter()
        .fold(i32::MIN, |prev, cur| {
            if prev > *cur {
                prev
            } else {
                *cur
            }
        });
    
    // 위와 마찬가지  
    let smallest = my_vec
        .iter()
        .fold(i32::MAX, |prev, cur| min(prev, *cur)); 
    
    // +operator 는 &i32에 대해 구현되어있음
    let sum = my_vec
        .iter()
        .fold(0, |prev, cur| prev + cur); 
    
    
    
    println!("Biggest:{biggest}");
    println!("Smallest:{smallest}");
    println!("Sum:{sum}");
}

chunks, windows

// .take_while // .take() 가 있음
// .cloned
// .by_ref
// .skip_while
// .map_while

#[allow(unused_imports)]

fn main() {
    
    let n = vec![1,2,3,4,5,6,7,8,9,0];
    
    
    // .chunks // 1,2,3 | 4,5,6 | 7,8,9
    println!("chunks");
    for chunk in n.chunks(3) {
        println!("{chunk:?}");
    }
    
    // .windows는 좀 더 계산이 들어감?
    println!("window");
    for window in n.windows(3) {
        println!("{window:?}");
    }
}


chunks
[1, 2, 3]
[4, 5, 6]
[7, 8, 9]
[0]
window
[1, 2, 3]
[2, 3, 4]
[3, 4, 5]
[4, 5, 6]
[5, 6, 7]
[6, 7, 8]
[7, 8, 9]
[8, 9, 0]

match_indices

fn main() {
    
    let n = "A1: 1. A2: 2. A3: 3.";
    // string match된 index를 모두 구한다
    let a = n.match_indices("A").collect::<Vec<(_, _)>>();
    
    println!("{a:?}");
    
}
[(0, "A"), (7, "A"), (14, "A")]

peekable

#[allow(unused_imports)]

fn main() {
    
    let n = vec![1,5,100];
    // string match된 index를 모두 구한다
    let mut niter = n.iter().peekable();
    
    for _ in 0..3 {
        // next를 부르기 전까지 커서를 유지하는 iterator
        println!("{}", niter.peek().unwrap());
        println!("{}", niter.peek().unwrap());
        niter.next();
    }
     
}
1
1
5
5
100
100

dbg!

뭔가 빠르게 출력하기 위한 디버깅용 매크로 파일 입출력에 관한 정보도 출력해줌

fn main() {
    let my = 9;
    dbg!(my); // my = 9 변수명까지 출력됨

    let mut m = 9;
    dbg!(m+=10); // = ()

    let v = vec![8,9,10];
    let d = v.iter().map(|x| x*2).collect::<Vec<i32>>();

    // expression을 다 감쌀 수 있음
}

Inspect, String, &str

함수 중간에 에러가있는 경우 dbg를 쓸 수 없다. 그럴 때 inspect사용

fn main() {
    let new_vec = [8,9,10];
    let double_vec = new_vec
        .iter()
        .inspect(|x| {
            dbg!(x);
        })
        .map(|x| x*2)
        .inspect(|x| {
            dbg!(x); // 반환 하면 안됨
        })
        .filter(|n| n> 17)
        .collect::<Vec<_>>();

    dbg!(double_vec); 
}

lifetime

// &str를 구조체에 쓰면 구조체 메모리 해제후 참조가 어디로 가는지 모름..
// 그래서 lifetime지정해줘야함

struct Book<'a> {
    name: &'a str 
}

fn returns_reference() -> &'a str {
    let y = "David".to_string(); // &'static for the life of the program
    &y // expected lifetime specifier
    // 붙여도 여기서만 있는 lifetime이라 y의 참조를 반환할 수 없음
    // 'static 이면 가능
    
}

fn main() {
    let m = "David";

    let my_book = Book {
        name: "my book" 
    }
}


  • 라이프타임을 여러개 쓰는 경우가 있을 수 있나?
  • borrow checker를 생각한다.
  • 더 큰 lifetime을 가지는 변수는 작은 lifetime을 참조하면 안된다.
    • 즉 이미 메모리가 해제된 녀석(dangling reference)의 참조를 들고있지 않도록
  • struct에서 lifetime을 지정하는 이유도 마찬가지.
    • instance가 instance를 만들때 할당한 값보다 더 오래살면 안됨.
struct Adventurer<'a> {
    name: &'a str,
    hit_points: u32
}

// elided lifetime == 명시하지 않음
// implicit <'_> 
impl Adventurer<'_> {
    fn take_damage(&mut self) {
        self.hit_points -= 20;
        println!("{} has {} hit points left!", self.name, self.hit_points);
    }
}

<'a>Adventurer<'a>

Manual Debug impl

mod client {
    pub struct InternetClient {
        pub client_id: u32,
    }
}

use client::InternetClient;

#[derive(Debug)]
struct Customer<'a> {
    money: u32,
    name: &'a str,
    client: &'a InternetClient // 여기는 Debug가 없지?
}

impl fmt::Debug for Customer<'_> {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.debug_struct("Customer")
        .field("money", &self.money)
        .field("name", &self.name)
        .field("client", &"Client")
        .finish()
        
    }

}


  • debug, clone, partial은 거의 편리를 위해 구현하는 편

Referred in

Rust easy rust 86~92